package com.ljm.boot.service;


import com.ljm.boot.domain.ArticleSearchDTO;
import com.ljm.boot.domain.UserEntity;
import com.ljm.boot.repository.UserEsRepository;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;


@Service
public class UserService {

    @Autowired
    private UserEsRepository userEsRepository;

    @Resource
    private ElasticsearchRestTemplate elasticTemplate;

    public UserEntity getUserById(UserEntity user)  {
        Optional<UserEntity> op = userEsRepository.findById(user.getId());
        return (UserEntity) op.orElse(null);
    }

    public List<UserEntity> getUser(UserEntity user)  {
        List<UserEntity> userList = new ArrayList<>();
        Iterable<UserEntity> all = userEsRepository.findAll(Sort.by(Sort.Order.desc("id")));
        all.forEach(userList::add);
        return userList;
    }

    public void saveUser(UserEntity user)  {
        System.out.println(elasticTemplate);
        userEsRepository.save(user);
    }

    public void testSearchFromES(ArticleSearchDTO articleSearchDTO){
        //完整的合法 id
        String id = articleSearchDTO.getId();
        //非法 id
        String notId = articleSearchDTO.getNotId();
        //搜索框输入的内容（实际会从标签/内容/标题中查找）
        String searchText = articleSearchDTO.getSearchWord();
        //单独在标题中查找
        String title = articleSearchDTO.getTitle();
        //单独在内容中查找
        String content = articleSearchDTO.getContent();
        //单独在标签中查找(全部标签)
        List<String> tagList = articleSearchDTO.getTags();
        //任意标签
        List<String> orTagList = articleSearchDTO.getOrTags();
        //按照创建者的 userId 查找
        String userId = articleSearchDTO.getUserId();
        // 布尔查询初始化
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        // 过滤，首先被删除的就不要了
        //boolQueryBuilder.filter(QueryBuilders.termQuery(this.fn.fnToFieldName(ESArticle::getIsDelete), NumberUtils.INTEGER_ZERO));
        //如果输入的是 id 那么就不对 id 分词，然后过滤掉不符合该 id 的其它文档
        if (StringUtils.isNotBlank(id)) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("id", id));
        }
        //如果输入的是非法 id 那么什么也查不到，取反（也就是所有）返回
        if (StringUtils.isNotBlank(notId)) {
            boolQueryBuilder.mustNot(QueryBuilders.termQuery("id", notId));
        }
        //创建者 userId 也不分词，过滤掉不匹配的
        if (StringUtils.isNotBlank(userId)) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("createId", userId));
        }
        // 必须包含所有标签
        if (tagList!=null) {
            for (String tag : tagList) {
                boolQueryBuilder.filter(QueryBuilders.termQuery("tags", tag));
            }
        }
        // 包含任何一个标签即可
        if (orTagList!=null) {
            BoolQueryBuilder orTagBoolQueryBuilder = QueryBuilders.boolQuery();
            // DB 实体中 tag 字段为 String，而 ES 实体该字段的类型为 List，所以做循环遍历
            for (String tag : orTagList) {
                orTagBoolQueryBuilder.should(QueryBuilders.termQuery("tags", tag)).minimumShouldMatch(1);
            }
            //filter 可以结合 bool 做更复杂的过滤
            boolQueryBuilder.filter(orTagBoolQueryBuilder);
        }
        // 按关键词检索（主要的搜索框，关键词会在两个字段里匹配）
        if (StringUtils.isNotBlank(searchText)) {
            boolQueryBuilder.should(QueryBuilders.matchQuery("title", searchText));
            boolQueryBuilder.should(QueryBuilders.matchQuery("content", searchText));
            boolQueryBuilder.minimumShouldMatch(1);
        }
        // 单独按标题检索
        if (StringUtils.isNotBlank(title)) {
            boolQueryBuilder.should(QueryBuilders.matchQuery("title", title));
        }
        // 单独按内容检索
        if (StringUtils.isNotBlank(content)) {
            boolQueryBuilder.should(QueryBuilders.matchQuery("content", content));
        }
    }

}